import java.util.PriorityQueue;
import java.util.Timer;

class MyTimerTask implements Comparable<MyTimerTask>{
    private Runnable runnable;
    private long time;

    public long getTime(){
        return time;
    }

    public MyTimerTask(Runnable runnable,long delay){
        this.runnable = runnable;
        this.time = System.currentTimeMillis() + delay;
    }

    public void run (){
        runnable.run();
    }

    public int compareTo(MyTimerTask o) {
        return (int)(this.time - o.getTime());
    }

}

class MyTimer{
    private PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();

    private Object locker = new Object();

    public void schedule(Runnable runnable,long delay){
        synchronized (locker){
            MyTimerTask task = new MyTimerTask(runnable,delay);
            queue.add(task);
            locker.notify();
        }


    }

    public MyTimer() {
        Thread t = new Thread(() -> {
            try{
                while(true){
                    synchronized (locker){
                        MyTimerTask myTimerTask = queue.peek();
                        while(myTimerTask == null){
                            locker.wait();
                            myTimerTask = queue.peek();
                        }
                        long curtime = System.currentTimeMillis();
                        if(myTimerTask.getTime() <= curtime){
                            myTimerTask.run();
                            queue.poll();
                        }else{
                            locker.wait(myTimerTask.getTime() - curtime);
                        }
                    }
                }
            }catch(InterruptedException e){
                throw new RuntimeException("wait 终止");
            }
        });
        t.start();
    }
}




public class Demo3 {
    public static void main(String[] args) {
        MyTimer my = new MyTimer();
        my.schedule(() -> {
            System.out.println(3000);
        },3000);
        my.schedule(() -> {
            System.out.println(2000);
        },2000);
        my.schedule(() -> {
            System.out.println(1000);
        },1000);
    }
}
